﻿using System;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;

namespace Microsoft.WowAddonStudio.Project.Import
{
	/// <summary>
	/// Implements an addon item for ace import.
	/// </summary>
	public class AceAddonItem : AddonItem
	{
		private readonly string zipLocation;
		private readonly string entryName;

		#region Lifecycle methods

		/// <summary>
		/// Creates an instance of <see cref="AceAddonItem"/>.
		/// <param name="relativePath">Location of addon item relative to location of import.</param>
		/// <param name="zipLocation">Location of source zip file</param>
		/// <param name="entryName">Name of entry in the zip file</param>
		/// </summary>
		public AceAddonItem(string relativePath, string zipLocation, string entryName)
			: base(relativePath)
		{
			if (string.IsNullOrEmpty(zipLocation))
				throw new ArgumentNullException("zipLocation");
			if (string.IsNullOrEmpty(entryName))
				throw new ArgumentNullException("entryName");

			this.zipLocation = zipLocation;
			this.entryName = entryName;
		}

		#endregion

		#region Public overrides

		/// <summary>
		/// Gets the contents of the addon item as a stream.
		/// </summary>
		/// <returns>
		/// An instance of the <see cref="Stream"/> class.
		/// </returns>
		public override Stream GetStream()
		{
			var result = new MemoryStream();

			using (var baseFileStream = File.Open(zipLocation, FileMode.Open, FileAccess.Read))
			{
				using (var s = new ZipInputStream(baseFileStream))
				{
					//Find the appropriate entry
					ZipEntry theEntry;

					do
					{
						theEntry = s.GetNextEntry();
					} while (theEntry.Name != entryName);

					if (theEntry != null)
					{
						int size = 2048;
						byte[] data = new byte[2048];
						while (true)
						{
							size = s.Read(data, 0, data.Length);
							if (size > 0)
								result.Write(data, 0, size);
							else
								break;
						}
					}
					else
						throw new ApplicationException("Entry not found in zip file.");
				}
			}

			result.Seek(0, SeekOrigin.Begin);
			return result;
		}

		#endregion
	}
}